package com.fishery.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fishery.base.entity.ConstantValue;
import com.fishery.base.entity.PondFeeding;
import com.fishery.base.entity.SupplyOut;
import com.fishery.base.entity.vo.FeedingRecordVo;
import com.fishery.base.mapper.BaseSupplyMapper;
import com.fishery.base.mapper.PondFeedingMapper;
import com.fishery.base.service.PondFeedingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fishery.base.service.SupplyOutService;
import com.fishery.base.util.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Ghost
 * @since 2021-01-15
 */
@Service
public class PondFeedingServiceImpl extends ServiceImpl<PondFeedingMapper, PondFeeding> implements PondFeedingService {

	@Autowired
	private PondFeedingMapper pondFeedingMapper;

	@Autowired
	private SupplyOutService supplyOutService;

	@Autowired
	private BaseSupplyMapper baseSupplyMapper;

	@Autowired
	private ExecutorService threadPool;

	@Override
	public Page<FeedingRecordVo> pageBaseFeedingRecords(String baseId, int current, int size) {
		Page<FeedingRecordVo> page = new Page<>(current, size);
		Future<List<FeedingRecordVo>> future = threadPool.submit(() ->
				pondFeedingMapper.findAllBaseFeedingWithPage(baseId, (current - 1) * size, size));
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.eq("base_id", baseId);
		int total = pondFeedingMapper.selectCount(wrapper);
		page.setTotal(total);
		page.setPages(total / size + (total % size == 0 ? 0 : 1));
		try {
			page.setRecords(future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return page;
	}

	@Override
	public Page<FeedingRecordVo> pagePondFeedingRecords(String pondId, int current, int size) {
		Page<FeedingRecordVo> page = new Page<>(current, size);
		Future<List<FeedingRecordVo>> future = threadPool.submit(() ->
				pondFeedingMapper.findPondFeedingWithPage(pondId, (current - 1) * size, size));
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.eq("pond_id", pondId);
		int total = pondFeedingMapper.selectCount(wrapper);
		page.setTotal(total);
		page.setPages(total / size + (total % size == 0 ? 0 : 1));
		try {
			page.setRecords(future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return page;
	}

	@Override
	@Transactional
	public boolean feeding(PondFeeding pondFeeding) {
		// 投入品出库，进行记录
		threadPool.submit(() -> {
			SupplyOut supplyOut = new SupplyOut();
			BeanUtils.copyProperties(pondFeeding, supplyOut);
			supplyOut.setSupplyTypeName(pondFeeding.getSupplyType());
			supplyOut.setOutWeight(pondFeeding.getFeedingVolume());
			supplyOutService.createSupplyOutRecords(supplyOut);
		});
		// 保存喂养信息
		return pondFeedingMapper.insert(pondFeeding) > 0;
	}

	@Override
	@Transactional
	public boolean updateFeedingRecord(PondFeeding pondFeeding) {
		// 判断是否修改投喂量，如果是需要将投入品入库,这里不做入库记录，只增加库存量
		if (pondFeeding.getFeedingVolume().compareTo(ConstantValue.ZERO) > 0) {
			// 查看原来的喂养信息
			PondFeeding oldPondFeeding = pondFeedingMapper.selectById(pondFeeding.getId());
			// 计算出相差值
			BigDecimal delt = oldPondFeeding.getFeedingVolume().subtract(pondFeeding.getFeedingVolume());
			threadPool.submit(() -> {
				baseSupplyMapper.increaseBaseSupplyWeight(pondFeeding.getBaseId(), pondFeeding.getSupplyId(), delt);
			});
		}
		return pondFeedingMapper.updateById(pondFeeding) > 0;
	}

	@Override
	public void getFeedingRecordsByExcel(HttpServletResponse response, String baseId) {
		ExcelUtil.write(response, "基地喂养记录", FeedingRecordVo.class, "喂养记录", pondFeedingMapper.findAllBaseFeedingRecords(baseId));
	}

	@Override
	public Page<FeedingRecordVo> pageFeedingRecordsOfCurrentFarming(String farmingId, int current, int size) {
		Page<FeedingRecordVo> page = new Page(current, size);
		Future<List<FeedingRecordVo>> future = threadPool.submit(() ->
				pondFeedingMapper.findCurrentPondFeedingWithPage(farmingId, (current - 1) * size, size));
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.eq("farming_id", farmingId);
		int total = pondFeedingMapper.selectCount(wrapper);
		page.setTotal(total);
		page.setPages(total / size + total % size == 0 ? 0 : 1);
		try {
			page.setRecords(future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return page;
	}

	@Override
	public Page<FeedingRecordVo> traceFeedingByFarmingId(String farmingId, int current, int size, String catchTime) {
		Page<FeedingRecordVo> page = new Page(current, size);
		Future<List<FeedingRecordVo>> future = threadPool.submit(() ->
				pondFeedingMapper.findPondFeedingWithPageEvenDelete(farmingId, (current - 1) * size, size, catchTime));
		int total = pondFeedingMapper.selectCountEvenDelete(farmingId, catchTime);
		page.setTotal(total);
		page.setPages(total / size + total % size == 0 ? 0 : 1);
		try {
			page.setRecords(future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return page;
	}
}
